package com.gitee.dolt.boot.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gitee.dolt.annotation.log.SysLog;
import com.gitee.dolt.boot.request.PageParams;
import com.gitee.dolt.boot.request.QueryParams;
import com.gitee.dolt.boot.service.SuperCacheService;
import com.gitee.dolt.boot.service.SuperService;
import com.gitee.dolt.annotation.security.PreAuth;
import com.gitee.dolt.core.base.Result;
import com.gitee.dolt.core.exception.code.ExceptionCode;
import com.gitee.dolt.core.util.BizAssert;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.io.Serializable;
import java.util.List;


/**
 * 查询
 *
 * @author LYH
 */
public interface QueryController<Entity, Id extends Serializable, QueryDTO> extends BaseController<Entity> {

    /**
     * 处理分页参数
     *
     * @param params
     */
    default void handlerQueryParams(QueryParams<QueryDTO> params) {
    }

    /**
     * 处理Wrapper
     *
     * @param entity
     * @param params
     * @return
     */
    default QueryWrapper<Entity> handlerQueryWrapper(Entity entity, QueryParams<QueryDTO> params) {
        return entity == null ? Wrappers.query() : Wrappers.query(entity);
    }

    /**
     * @param page
     */
    default void handlerPageResult(IPage<Entity> page) {

    }

    /**
     * 主键查询
     *
     * @param id 主键id
     * @return
     */
    @ApiOperation(value = "主键查询")
    @GetMapping("/{id}")
    @SysLog("'查询:' + #id")
    @PreAuth("hasAnyPermission('{}view')")
    default Result get(@PathVariable Id id) {
        Result result = handlerGet(id);
        if (result.isExecDefault()) {
            SuperService<Entity> baseService = getBaseService();
            if (baseService instanceof SuperCacheService) {
                SuperCacheService superCacheService = (SuperCacheService) baseService;
                result.setData(superCacheService.getByIdCache(id));
            } else {
                result.setData(baseService.getById(id));
            }
        }
        return result;
    }

    /**
     * 批量查询
     *
     * @param params 条件参数
     * @return
     */
    @ApiOperation(value = "批量查询")
    @PostMapping("/query")
    @SysLog("批量查询")
    @PreAuth("hasAnyPermission('{}view')")
    default Result query(@RequestBody @Validated QueryParams<QueryDTO> params) {
        this.handlerQueryParams(params);
        Result result = handlerQuery(params);
        if (!result.isExecDefault()) {
            return result;
        }
        if (!enableQuery()) {
            BizAssert.fail(ExceptionCode.NOT_FOUND, "接口未被允许");
        }
        Entity entity = toBean(params.getModel());
        QueryWrapper<Entity> queryWrapper = this.handlerQueryWrapper(entity, params);
        List<OrderItem> orders = params.getOrders();
        orders.forEach(orderItem -> {
            queryWrapper.orderBy(true, orderItem.isAsc(), orderItem.getColumn());
        });
        result.setData(getBaseService().list(queryWrapper));
        return result;
    }

    /**
     * 分页查询
     *
     * @param params 分页参数
     * @return
     */
    @ApiOperation(value = "分页查询")
    @PostMapping(value = "/page")
    @SysLog(value = "'分页列表查询:第' + #params?.current + '页, 显示' + #params?.size + '行'")
    @PreAuth("hasAnyPermission('{}view')")
    default Result page(@RequestBody @Validated PageParams<QueryDTO> params) {
        this.handlerQueryParams(params);
        Result result = handlerPage(params);
        if (result.isExecDefault()) {
            IPage<Entity> page = params.buildPage();
            Entity entity = toBean(params.getModel());
            QueryWrapper<Entity> queryWrapper = this.handlerQueryWrapper(entity, params);
            IPage<Entity> entityPage = getBaseService().page(page, queryWrapper);
            this.handlerPageResult(entityPage);
            result.setData(entityPage);
        }
        return result;
    }

    /**
     * 自定义查询
     *
     * @param id id
     * @return 返回execDefault=true, 调用默认更新, 返回其他不调用默认更新
     */
    default Result handlerGet(Id id) {
        return Result.execDefault(true);
    }

    /**
     * 自定义列表
     *
     * @param params params
     * @return 返回execDefault=true, 调用默认更新, 返回其他不调用默认更新
     */
    default Result handlerQuery(QueryParams<QueryDTO> params) {
        return Result.execDefault(true);
    }

    /**
     * 自定义分页
     *
     * @param params params
     * @return 返回execDefault=true, 调用默认更新, 返回其他不调用默认更新
     */
    default Result handlerPage(PageParams<QueryDTO> params) {
        return Result.execDefault(true);
    }

    /**
     * 允许列表
     *
     * @return
     */
    default boolean enableQuery() {
        return false;
    }


}
